﻿#include "IPluginParam.h"

#include <QMetaProperty>
#include <QMetaObject>
#include <QDebug>

#include "MapVector.h"


namespace CVV
{

namespace Interface
{


IPluginParam::IPluginParam(QObject *parent)
    : QObject(parent)
    , m_dMeanValue(0)
    , m_iStatus(NotRunning)
    , m_bIsSuccess(false)
    , m_fElapsedTime(0)
    , m_bIsDefect(false)
    , m_iPictureId(0)
    , m_bIsModelData(false)
    , m_bIsLoopParam(false)
    , m_bIsExamples(false)
{
    qRegisterMetaType<RunStatus>("RunStatus");
    qRegisterMetaType<CVV::Entity::RoiRectEntity>("CVV::Entity::RoiRectEntity");
    qRegisterMetaType<QList<CVV::Entity::RoiRectEntity>>("QList<CVV::Entity::RoiRectEntity>");
    qRegisterMetaType<CVV::Entity::MapVariable>("CVV::Entity::MapVariable");
    qRegisterMetaType<QList<CVV::Entity::MapVariable>>("QList<CVV::Entity::MapVariable>");
    qRegisterMetaType<CVV::Entity::MapVector>("CVV::Entity::MapVector");
    qRegisterMetaType<QList<CVV::Entity::MapVector>>("QList<CVV::Entity::MapVector>");
    qRegisterMetaType<QList<std::shared_ptr<AbstractEntity>>>("QList<std::shared_ptr<AbstractEntity>>");
    qRegisterMetaType<std::shared_ptr<AbstractEntity>>("std::shared_ptr<AbstractEntity>");

}

IPluginParam::IPluginParam(const IPluginParam &cellParam)
{
    if (this == &cellParam)
    {
        return;
    }

    this->m_strCode = cellParam.getT_code();
    this->m_strError = cellParam.getT_error();
    this->m_strId = cellParam.getT_id();
    this->m_bIsSuccess = cellParam.getT_isSuccess();
    this->m_iStatus = cellParam.getT_status();
    this->m_fElapsedTime = cellParam.getT_elapsedTime();
    this->m_strTitle = cellParam.getT_title();
    this->m_outImage = cellParam.getO_image();
    this->m_strSelectImagePath = cellParam.getO_SelectImagePath();
    this->m_secondInputImage = cellParam.getSecondInputImage();
    this->m_SelectTestImagePath = cellParam.getSelectTestImagePath();
    this->m_detectRectF = cellParam.getActuralDetectRectF();
    this->m_detectPolygon = cellParam.getActuralDetectPolygon();
    this->m_detectCircle = cellParam.getActuralDetectCircle();

    this->m_lstPolygonPoints = cellParam.getPolygonPoints();
    this->m_bIsDefect = cellParam.getIsDefect();
    this->m_strPreId = cellParam.getPreId();
    this->m_dMeanValue = cellParam.getMeanValue();
    this->m_strOutImageHeader = cellParam.getO_imageHeader();
    this->m_bIsModelData = cellParam.getIsModelData();
    this->m_mapDynamicProperty = cellParam.getDynamicProperty();

    m_bIsLoopParam = cellParam.getIsLoopParam();
    m_iPictureId = cellParam.getPictureId();
    m_bIsExamples = cellParam.getIsExamples();
}

IPluginParam::~IPluginParam()
{
//    qDebug() << __func__;
}

IPluginParam& IPluginParam::operator=(const IPluginParam &cellParam)
{
    if (this == &cellParam)
    {
        return *this;
    }

    this->m_strCode = cellParam.getT_code();
    this->m_strError = cellParam.getT_error();
    this->m_strId = cellParam.getT_id();
    this->m_bIsSuccess = cellParam.getT_isSuccess();
    this->m_iStatus = cellParam.getT_status();
    this->m_fElapsedTime = cellParam.getT_elapsedTime();
    this->m_strTitle = cellParam.getT_title();
    this->m_outImage = cellParam.getO_image();
    this->m_strSelectImagePath = cellParam.getO_SelectImagePath();
    this->m_secondInputImage = cellParam.getSecondInputImage();
    this->m_SelectTestImagePath = cellParam.getSelectTestImagePath();
    this->m_detectRectF = cellParam.getActuralDetectRectF();
    this->m_detectPolygon = cellParam.getActuralDetectPolygon();
    this->m_detectCircle = cellParam.getActuralDetectCircle();

    this->m_lstPolygonPoints = cellParam.getPolygonPoints();
    this->m_bIsDefect = cellParam.getIsDefect();
    this->m_strPreId = cellParam.getPreId();
    this->m_dMeanValue = cellParam.getMeanValue();
    this->m_strOutImageHeader = cellParam.getO_imageHeader();
    this->m_bIsModelData = cellParam.getIsModelData();
    this->m_mapDynamicProperty = cellParam.getDynamicProperty();

    m_bIsLoopParam = cellParam.getIsLoopParam();
    m_iPictureId = cellParam.getPictureId();
    m_bIsExamples = cellParam.getIsExamples();

    return *this;
}

QString IPluginParam::getT_error() const
{
    return m_strError;
}

void IPluginParam::setT_error(const QString &value)
{
    m_strError = value;
}

bool IPluginParam::getT_isSuccess() const
{
    return m_bIsSuccess;
}

void IPluginParam::setT_isSuccess(bool value)
{
    m_bIsSuccess = value;
}
QString IPluginParam::getT_id() const
{
    return m_strId;
}

void IPluginParam::setT_id(const QString &value)
{
    m_strId = value;
}

QString IPluginParam::getT_title() const
{
    return m_strTitle;
}

void IPluginParam::setT_title(const QString &value)
{
    m_strTitle = value;
}

QString IPluginParam::getT_code() const
{
    return m_strCode;
}

void IPluginParam::setT_code(const QString &value)
{
    m_strCode = value;
}

QString IPluginParam::getSelectTestImagePath() const
{
    return m_SelectTestImagePath;
}

void IPluginParam::setSelectTestImagePath(const QString &value)
{
    m_SelectTestImagePath = value;
}


QDomElement IPluginParam::toDomElement()
{
    QDomDocument doc;
    QDomElement element=doc.createElement(getT_code());
    const QMetaObject* metaObj = this->metaObject();
    int propertyCnt = metaObj->propertyCount();
    for ( int i = 1; i < propertyCnt; ++i )
    {
        QMetaProperty oneProperty = metaObj->property(i);
        element.setAttribute(oneProperty.name(),this->property(oneProperty.name()).toString());
    }
    return  element;
}

cv::Mat IPluginParam::getT_inputImage() const
{
    return m_inputImage;
}

void IPluginParam::setT_inputImage(const cv::Mat &value)
{
    m_inputImage = value;
}

cv::Mat IPluginParam::getSecondInputImage() const
{
    return m_secondInputImage;
}

void IPluginParam::setSecondInputImage(const cv::Mat &value)
{
    m_secondInputImage = value;
}



cv::Mat IPluginParam::getO_image() const
{
    return m_outImage;
}

void IPluginParam::setO_image(const cv::Mat& value)
{
    m_outImage = value;
}

float IPluginParam::getT_elapsedTime() const
{
    return m_fElapsedTime;
}

void IPluginParam::setT_elapsedTime(float value)
{
    m_fElapsedTime = value;
}

RunStatus IPluginParam::getT_status() const
{
    return m_iStatus;
}

void IPluginParam::setT_status(const RunStatus &value)
{
    m_iStatus = value;
}

QString IPluginParam::getO_SelectImagePath() const
{
    return m_strSelectImagePath;
}

void IPluginParam::setO_SelectImagePath(const QString &value)
{
    m_strSelectImagePath = value;
}

QList<std::shared_ptr<AbstractEntity>> IPluginParam::getDetectRectF() const
{
    QList<std::shared_ptr<AbstractEntity>> lstRet;
    for (auto &rect : qAsConst(m_detectRectF))
    {
        lstRet.push_back(std::make_shared<CVV::Entity::RoiRectEntity>(rect));
    }
    return lstRet;
}

QList<Entity::RoiRectEntity> IPluginParam::getActuralDetectRectF() const
{
    return m_detectRectF;
}

void IPluginParam::setDetectRectF(const QList<std::shared_ptr<AbstractEntity>> &value)
{
    m_detectRectF.clear();
    for (auto &data : qAsConst(value))
    {
        std::shared_ptr<RoiRectEntity> pRect = std::dynamic_pointer_cast<RoiRectEntity>(data);
        if (pRect)
        {
            m_detectRectF.push_back(*pRect);
        }
    }
}

QList<QRectF> IPluginParam::getQRectF() const
{
    QList<QRectF> recVev;
    for(auto rect : m_detectRectF)
    {
        QRectF re;
        QPointF tl(QPointF(rect.getTopLeftX(),rect.getTopLeftY()));
        re.setTopLeft(tl);
        re.setWidth(rect.getWidth());
        re.setHeight(rect.getHeight());
        recVev.push_back(re);
    }
    return recVev;
}

QList<QPolygonF> IPluginParam::getAllQRectPoint() const
{
    QList<QPolygonF> recVev;
    for(auto rect : m_detectRectF)
    {
        QPolygonF poly;
        poly.append(rect.getRectPoint().toVector());
        recVev.push_back(poly);
    }
    return recVev;
}

QList<QPolygonF> IPluginParam::getAllQPolygonPoint() const
{
    QList<QPolygonF> recVev;
    for(auto rect : m_detectPolygon)
    {
        QPolygonF poly;
        poly.append(rect.getPolyPointList().toVector());
        recVev.push_back(poly);
    }
    return recVev;
}

QList<QPair<QPointF,float>> IPluginParam::getAllQCirclePoint() const
{
    QList<QPair<QPointF,float>> cirList;
    for(auto rect : m_detectCircle)
    {
        QPair<QPointF,float> pa;
        pa.first = QPointF(rect.getX(),rect.getY());
        pa.second = rect.getRadius();
        cirList.push_back(pa);
    }
    return cirList;
}


QList<QPair<QPointF,QPair<float,float>>> IPluginParam::getAllQCircleRingInfo() const
{
    QList<QPair<QPointF,QPair<float,float>>> cirringlist;
    for(auto rect : m_detectCircle)
    {
        QPair<QPointF,QPair<float,float>> pa;
        pa.first = QPointF(rect.getX(),rect.getY());
        QPair<float,float> radpair;
        radpair.first = rect.getRadius();
        radpair.second = rect.getOutRadius();
        pa.second = radpair;
        cirringlist.push_back(pa);
    }
    return cirringlist;
}

bool IPluginParam::getIsModelData() const
{
    return m_bIsModelData;
}

void IPluginParam::setIsModelData(bool value)
{
    m_bIsModelData = value;
}

int IPluginParam::getPictureId() const
{
    return m_iPictureId;
}

void IPluginParam::setPictureId(const int value)
{
    m_iPictureId = value;
}

bool IPluginParam::hasDynamicProperty(const QString &name) const
{
    return m_mapDynamicProperty.keys().contains(name);
}

void IPluginParam::setDynamicPropertyValue(const QMap<QString, QVariant> &mapValue)
{
    m_mapDynamicProperty.clear();
    m_mapDynamicProperty = mapValue;
}

QVariant IPluginParam::getDynamicPropertyValue(const QString &name) const
{
    return m_mapDynamicProperty.value(name);
}

QMap<QString, QVariant> IPluginParam::getDynamicProperty() const
{
    return m_mapDynamicProperty;
}

void IPluginParam::setIsLoopParam(bool value)
{
    m_bIsLoopParam = value;
}

bool IPluginParam::getIsLoopParam() const
{
    return m_bIsLoopParam;
}

void IPluginParam::setIsExamples(bool value)
{
    m_bIsExamples = value;
}

bool IPluginParam::getIsExamples() const
{
    return m_bIsExamples;
}

void IPluginParam::resetRunData()
{
    if (m_bIsModelData)
    {
        return;
    }

    m_iStatus = NotRunning;
    m_bIsSuccess = false;
    m_strError.clear();
    m_fElapsedTime = 0.0;
    m_strOutImageHeader.clear();
    m_mapDynamicProperty.clear();
    m_outImage = cv::Mat();
    m_inputImage = cv::Mat();
    m_secondInputImage = cv::Mat();

    m_detectCircle.clear();
    m_detectPolygon.clear();
    m_detectRectF.clear();
    m_detectVariable.clear();
    m_bIsLoopParam = false;
    m_bIsExamples = false;
}

QString IPluginParam::getO_imageHeader() const
{
    return m_strOutImageHeader;
}

void IPluginParam::setO_imageHeader(const QString &imageHeader)
{
    m_strOutImageHeader = imageHeader;
    QString str = imageHeader.mid(0, imageHeader.lastIndexOf("."));
    QStringList lstStr = str.split("-");
    if (lstStr.size() == 3)
    {
        m_iPictureId = lstStr.at(2).toInt();
    }
    else if (lstStr.size() >= 5)
    {
        m_iPictureId = lstStr.at(3).toInt();
    }
}


void IPluginParam::setsQRectF(const QList<QRectF> &rectVec)
{
    m_detectRectF.clear();
    for(auto rectf : rectVec)
    {
        RoiRectEntity entity;// = new RoiRectEntity(this);
        entity.setRectF(rectf);
        m_detectRectF.push_back(entity);
    }
}

QList<QPoint> IPluginParam::getPolygonPoints() const
{
    return m_lstPolygonPoints;
}

void IPluginParam::setPolygonPoints(const QList<QPoint> &value)
{
    m_lstPolygonPoints = value;
}

bool IPluginParam::getIsDefect() const
{
    return m_bIsDefect;
}

void IPluginParam::setIsDefect(bool value)
{
    m_bIsDefect = value;
}

QString IPluginParam::getPreId() const
{
    return m_strPreId;
}

void IPluginParam::setPreId(const QString &value)
{
    m_strPreId = value;
}

QMultiMap<QString, QString> IPluginParam::getSelectPathAssociationCode() const
{
    return m_mapSelectPathAssociationCode;
}

void IPluginParam::setSelectPathAssociationCode(const QMultiMap<QString, QString> &value)
{
    m_mapSelectPathAssociationCode = value;
}

QString IPluginParam::getAlgoritmPluginCode() const
{
    QString strAlgCode = m_strCode;
    if (!strAlgCode.endsWith("Algorithm"))
    {
        strAlgCode += "Algorithm";
    }

    return strAlgCode;
}

double IPluginParam::getMeanValue() const
{
    return m_dMeanValue;
}

void IPluginParam::setMeanValue(const double &value)
{
    m_dMeanValue = value;
}

QList<std::shared_ptr<AbstractEntity>> IPluginParam::getDetectVariable() const
{
    QList<std::shared_ptr<AbstractEntity>> lstVar;
    for (auto &var : qAsConst(m_detectVariable))
    {
        lstVar.push_back(std::make_shared<CVV::Entity::MapVariable>(var));
    }
    return lstVar;
}

void IPluginParam::setDetectVariable(const QList<std::shared_ptr<AbstractEntity>> &value)
{
    m_detectVariable.clear();
    for (auto &data : qAsConst(value))
    {
        std::shared_ptr<MapVariable> var = std::dynamic_pointer_cast<MapVariable>(data);
        if (var)
        {
            m_detectVariable.push_back(*var);
        }
    }
}


QList<std::shared_ptr<AbstractEntity>> IPluginParam::getDetectPolygon() const
{
    QList<std::shared_ptr<AbstractEntity>> lstRet;
    for (auto &poly : qAsConst(m_detectPolygon))
    {
        lstRet.push_back(std::make_shared<CVV::Entity::Polygon>(poly));
    }
    return lstRet;
}

QList<Entity::Polygon> IPluginParam::getActuralDetectPolygon() const
{
    return m_detectPolygon;
}

void IPluginParam::setDetectPolygon(const QList<std::shared_ptr<AbstractEntity>> &value)
{
    m_detectPolygon.clear();
    for (auto &data : qAsConst(value))
    {
        std::shared_ptr<Polygon> poly = std::dynamic_pointer_cast<Polygon>(data);
        if (poly)
        {
            m_detectPolygon.push_back(*poly);
        }
    }
}

QList<std::shared_ptr<AbstractEntity>> IPluginParam::getDetectCircle() const
{
    QList<std::shared_ptr<AbstractEntity>> lstRet;
    for (auto &cir : qAsConst(m_detectCircle))
    {
        lstRet.push_back(std::make_shared<CVV::Entity::Circular>(cir));
    }
    return lstRet;
}

QList<Entity::Circular> IPluginParam::getActuralDetectCircle() const
{
    return m_detectCircle;
}

void IPluginParam::setDetectCircle(const QList<std::shared_ptr<AbstractEntity>> &value)
{
    m_detectCircle.clear();
    for (auto &data : qAsConst(value))
    {
        std::shared_ptr<Circular> cir = std::dynamic_pointer_cast<Circular>(data);
        if (cir)
        {
            m_detectCircle.push_back(*cir);
        }
    }
}

}

}
